package com.handydata.antifraud.service.impl;

import com.alibaba.fastjson.JSON;
import com.handydata.antifraud.bo.datacalllogs.DataCallLogsBeanExtBO;
import com.handydata.antifraud.bo.orderbaseinfo.*;
import com.handydata.antifraud.channel.RabbitSender;
import com.handydata.antifraud.common.constant.DictInfoCode;
import com.handydata.antifraud.common.constant.OrderProcessStateCode;
import com.handydata.antifraud.common.exception.OrderBaseInfoExCode;
import com.handydata.antifraud.dao.DataCallLogsDao;
import com.handydata.antifraud.dao.DictInfoDao;
import com.handydata.antifraud.dao.OrderBaseInfoDao;
import com.handydata.antifraud.entity.DataCallLogsDO;
import com.handydata.antifraud.entity.OrderBaseInfoDO;
import com.handydata.antifraud.entity.OrderBaseInfoExtDO;
import com.handydata.antifraud.entity.QueryOrderListDO;
import com.handydata.antifraud.enums.ProcessStatusEnum;
import com.handydata.antifraud.service.DictInfoService;
import com.handydata.antifraud.service.OrderBaseInfoService;
import com.handydata.common.convert.CommonBeanConvertor;
import com.handydata.common.exception.SysException;
import com.handydata.common.service.AbsService;

import com.handydata.common.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service("orderBaseInfoService")
public class OrderBaseInfoServiceImpl extends AbsService implements OrderBaseInfoService {
	
	private static final Logger logger = LoggerFactory.getLogger(OrderBaseInfoServiceImpl.class);
	
	@Autowired
	private OrderBaseInfoDao orderBaseInfoDao;
	@Autowired
	private DataCallLogsDao dataCallLogsDao;
	@Autowired
	private DictInfoDao dictInfoDao;
	@Autowired
	private DictInfoService dictInfoService;

	@Autowired
	private RabbitSender rabbitSender;

	@Autowired
	private RedisUtil redisUtil;
	@Transactional
	@Override
	public OrderBaseInfoResBO createOrderBaseInfo(OrderBaseInfoReqBO req) throws SysException{
	    OrderBaseInfoResBO res = new OrderBaseInfoResBO();
		try {
			OrderBaseInfoDO entity = CommonBeanConvertor.convert(req, OrderBaseInfoDO.class);
			entity.setId(UUID.randomUUID().toString().replace("-", ""));	
			long status = orderBaseInfoDao.insert(entity);
			if(status == 0) {
				res.setExCode(OrderBaseInfoExCode.SYS_NO_ENTITY_CREATED);
			} else {
				res.setExCode(OrderBaseInfoExCode.SUCCESS);
			}
 			
		} catch (Exception e) {
			logger.error("Create new entity {} get into error", req, e);
			throw new SysException(OrderBaseInfoExCode.SYS_CREATE_ENTITY_ERROR);
		}
		
		return res;
	}

	@Transactional
	@Override
	public OrderBaseInfoResBO modifyOrderBaseInfo(OrderBaseInfoReqBO req) throws SysException{
	    OrderBaseInfoResBO res = new OrderBaseInfoResBO();
		try {
			OrderBaseInfoDO condition = CommonBeanConvertor.convert(req, OrderBaseInfoDO.class);
			long status = orderBaseInfoDao.update(condition);
			if(status == 0) {
				res.setExCode(OrderBaseInfoExCode.SYS_NO_ENTITY_MODIFIED);
			} else {
				res.setExCode(OrderBaseInfoExCode.SUCCESS);
			}
		} catch (Exception e) {
			logger.error("Modify entity {} get into error", req, e);
			throw new SysException(OrderBaseInfoExCode.SYS_MODIFY_ENTITY_ERROR);
		} 
		return res;
	}

	@Transactional
	@Override
	public OrderBaseInfoResBO deleteOrderBaseInfo(OrderBaseInfoReqBO req) throws SysException{
	    OrderBaseInfoResBO res = new OrderBaseInfoResBO();
		
		try {
			OrderBaseInfoDO condition = CommonBeanConvertor.convert(req, OrderBaseInfoDO.class);
			long status = orderBaseInfoDao.delete(condition);
			if(status == 0) {
				res.setExCode(OrderBaseInfoExCode.SYS_NO_ENTITY_DELETED);
			} else {
				res.setExCode(OrderBaseInfoExCode.SUCCESS);
			}
		} catch (Exception e) {
			logger.error("Delete entity {} get into error", req, e);
			throw new SysException(OrderBaseInfoExCode.SYS_DELETE_ENTITY_ERROR);
		}
		return res;
	}

	@Override
	public OrderBaseInfoResBO queryOrderBaseInfo(OrderBaseInfoReqBO req) throws SysException{
		OrderBaseInfoDO condition = CommonBeanConvertor.convert(req, OrderBaseInfoDO.class);
		OrderBaseInfoResBO res;
		
		try {
			OrderBaseInfoDO reqnew=new OrderBaseInfoDO();
			reqnew.setOrderId(condition.getOrderId());
			List<OrderBaseInfoDO> entities = orderBaseInfoDao.query(reqnew);
			res = CommonBeanConvertor.convert(entities, OrderBaseInfoResBO.class, OrderBaseInfoBeanBO.class);
		} catch(Exception e) {
			logger.error("Query entity {} get into error", req, e);
			throw new SysException(OrderBaseInfoExCode.SYS_QUERY_ENTITY_ERROR);
		}
		return res;
	}

	//@Transactional
	@Override
	public void saveDataToDbMqRedis(OrderBaseInfoReqBO orderBaseInfoReqBO) throws Exception {

//		QueryOrderListReqBO reqBO=new QueryOrderListReqBO();不去数据库检查是否存在记录了
//		reqBO.setOrderId(orderBaseInfoReqBO.getOrderId());

//		QueryOrderListResBO bo=queryOrderList(reqBO);
//		if(bo!=null&&bo.getBussinessEnterManageList().size()>0){
//			logger.info("该订单已经入库{},不再入库，但会发送mq",orderBaseInfoReqBO.getOrderId());
//		}else {
		logger.info("===============接收订单号orderID{},开始存入DB、redis、MQ",orderBaseInfoReqBO.getOrderId());
		logger.info("===============接收订单号orderID{},存入DB===============开始时间",orderBaseInfoReqBO.getOrderId());
			createOrderBaseInfo(orderBaseInfoReqBO);//入库成功算真的成功
		logger.info("===============接收订单号orderID{},存入DB===============结束时间",orderBaseInfoReqBO.getOrderId());
		//}
		logger.info("===============接收订单号orderID{},存入MQ===============开始时间",orderBaseInfoReqBO.getOrderId());
		rabbitSender.send(JSON.toJSONString(orderBaseInfoReqBO),orderBaseInfoReqBO.getOrderId());
		logger.info("===============接收订单号orderID{},存入MQ===============结束时间",orderBaseInfoReqBO.getOrderId());
		String rOrderID = "order_" + orderBaseInfoReqBO.getOrderId();
		redisUtil.set(rOrderID, 0, 86400);
	}

	/**
	 * 
	 * 业务进件管理列表查询
	 * @param req 请求BO参数
	 * @return
	 */
	@Override
	public QueryOrderListResBO queryOrderList(QueryOrderListReqBO req) {
		QueryOrderListResBO res;
		try {
			QueryOrderListDO condition = CommonBeanConvertor.convert(req, QueryOrderListDO.class);
			// 查询列表
			if (req.getPageSize() == null) {
				condition.setPageSize(10);
			} 
			condition.setPageSize(condition.getPageSize());
			if (req.getPageNumber() == null) {
				condition.setPageNumber(1);
			} 
			condition.setPageNumber((condition.getPageNumber() - 1) * (condition.getPageSize()));
			List<QueryOrderListDO> queryList = orderBaseInfoDao.queryOrderList(condition);
			// 统计信息总数
			int total = orderBaseInfoDao.countOrderList(condition);
			res = CommonBeanConvertor.convert(queryList, QueryOrderListResBO.class, QueryOrderListBeanBO.class);
			res.setTotalNumber(total);
			res.setTotalPage(total % condition.getPageSize() == 0 ? total/condition.getPageSize() : total/condition.getPageSize() + 1);
		} catch(Exception e) {
			logger.error("Query entity {} get into error", req, e);
			throw new SysException(OrderBaseInfoExCode.SYS_QUERY_ENTITY_ERROR);
		}
		logger.info("业务进件管理列表查询接口返回结果：{}", res);
		return res;
	}

	 /**
     * 业务进件详情查询
     * @param req
     * @return
     */
	@Override
	public EnterLetterDetailQueryResBO enterLetterDetailQuery(EnterLetterDetailQueryReqBO req) {
		EnterLetterDetailQueryResBO res = new EnterLetterDetailQueryResBO();
		try {
			// 查询订单详情
			OrderBaseInfoDO orderReq = new OrderBaseInfoDO();
			orderReq.setId(req.getId());
			OrderBaseInfoDO orderBaseInfo = orderBaseInfoDao.queryOne(orderReq);
			if (orderBaseInfo != null) {
				OrderBaseInfoExtDO orderBaseInfoExt = CommonBeanConvertor.convert(orderBaseInfo, OrderBaseInfoExtDO.class);
				Object merchantName = dictInfoService.getDictInfo(orderBaseInfo.getMerCode(),DictInfoCode.DICT_MERCHANT.getCode());
				orderBaseInfoExt.setMerchantName(String.valueOf(merchantName));
				Object productName = dictInfoService.getDictInfo(orderBaseInfo.getProductCode(),DictInfoCode.DICT_PRODUCT.getCode());
				orderBaseInfoExt.setProductName(String.valueOf(productName));
				if (ProcessStatusEnum.PENDING.getCode().equals(orderBaseInfo.getProcessState())){
					orderBaseInfoExt.setProcessState(OrderProcessStateCode.ORDER_PROCESS_UNTREATED.getValue());
				} else if (OrderProcessStateCode.ORDER_PROCESSING.getKey().equals(orderBaseInfo.getProcessState())){
					orderBaseInfoExt.setProcessState(OrderProcessStateCode.ORDER_PROCESSING.getValue());
				} else if (OrderProcessStateCode.ORDER_PROCESS_SUCCESS.getKey().equals(orderBaseInfo.getProcessState())){
					orderBaseInfoExt.setProcessState(OrderProcessStateCode.ORDER_PROCESS_SUCCESS.getValue());
				} else if (OrderProcessStateCode.ORDER_PROCESS_FAIL.getKey().equals(orderBaseInfo.getProcessState())){
					orderBaseInfoExt.setProcessState(OrderProcessStateCode.ORDER_PROCESS_FAIL.getValue());
				} else if (OrderProcessStateCode.ORDER_RETURN_SUCCESS.getKey().equals(orderBaseInfo.getProcessState())){
					orderBaseInfoExt.setProcessState(OrderProcessStateCode.ORDER_RETURN_SUCCESS.getValue());
				} else if (OrderProcessStateCode.ORDER_RETURN_FAIL.getKey().equals(orderBaseInfo.getProcessState())){
					orderBaseInfoExt.setProcessState(OrderProcessStateCode.ORDER_RETURN_FAIL.getValue());
				}
				res.setEnterLetterDetailInfo(orderBaseInfoExt);
				// 查询数据源调用情况列表
				DataCallLogsDO dataCallQueryReq = new DataCallLogsDO();
				dataCallQueryReq.setOrderId(orderBaseInfo.getOrderId());
				List<DataCallLogsDO> dataCallList = dataCallLogsDao.query(dataCallQueryReq);
				List<DataCallLogsBeanExtBO> dataInvokingList = dataCallList
						.stream()
						.map(x -> {
							DataCallLogsBeanExtBO convert = CommonBeanConvertor.convert(x, DataCallLogsBeanExtBO.class);
							convert.setDataName(String.valueOf(dictInfoService.getDictInfo(x.getDataType(),DictInfoCode.DICT_WS.getCode())));
							return convert;
						}).collect(Collectors.toList());
				res.setDataInvokingList(dataInvokingList);
			}
		} catch(Exception e) {
			logger.error("Query entity {} get into error", req, e);
			throw new SysException(OrderBaseInfoExCode.SYS_QUERY_ENTITY_ERROR);
		}
		logger.info("业务进件详情查询接口返回结果：{}", res);
		return res;
	}

	@Override
	public OrderBaseInfoResBO modifyOrderBaseInfoBy(OrderBaseInfoReqBO req) throws SysException {
		OrderBaseInfoResBO res = queryOrderBaseInfo(req);
		List<OrderBaseInfoBeanBO> orderBaseInfoBeanBO = res.getResultList();

		if(orderBaseInfoBeanBO.size() == 0) {
			throw new SysException(OrderBaseInfoExCode.SYS_MODIFY_ENTITY_EMPTY);
		}
		if(orderBaseInfoBeanBO.size() > 1) {
			//throw new SysException(OrderBaseInfoExCode.SYS_MODIFY_ENTITY_NOT_UNIQUE);
			logger.error("订单号{} 数据库记录有{}条，只更新第一条",req.getOrderId(),orderBaseInfoBeanBO.size());
		}
		req.setId(orderBaseInfoBeanBO.get(0).getId());
		return modifyOrderBaseInfo(req);
	}
}
